package com.service.impl;


import com.alibaba.fastjson.JSON;
import com.model.ReportPublicStr;
import com.model.ReportSiteValue;
import com.model.ReportStr;
import com.service.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service(value = "CalculateService")
public class CalculateStrService {
    private static final Logger log = LoggerFactory.getLogger(CalculateStrService.class);

    /**
     * 提取出给定位点库的位点信息
     *
     * @param reportStr
     * @return
     */
    public Map<String, String> getReportStrMap(ReportStr reportStr) {
        if (reportStr.getId() < 1) {
            return null;
        }
        Map<String, String> strMap = new HashMap<>();
        if (reportStr.getDys19() != null && Util.isDouble(reportStr.getDys19())) {
            strMap.put("dys19", reportStr.getDys19());
        }
        if (reportStr.getDys389i() != null && Util.isDouble(reportStr.getDys389i())) {
            strMap.put("dys389i", reportStr.getDys389i());
        }
        if (reportStr.getDys389b() != null && Util.isDouble(reportStr.getDys389b())) {
            strMap.put("dys389b", reportStr.getDys389b());
        }
        if (reportStr.getDys390() != null && Util.isDouble(reportStr.getDys390())) {
            strMap.put("dys390", reportStr.getDys390());
        }
        if (reportStr.getDys391() != null && Util.isDouble(reportStr.getDys391())) {
            strMap.put("dys391", reportStr.getDys391());
        }
        if (reportStr.getDys392() != null && Util.isDouble(reportStr.getDys392())) {
            strMap.put("dys392", reportStr.getDys392());
        }
        if (reportStr.getDys393() != null && Util.isDouble(reportStr.getDys393())) {
            strMap.put("dys393", reportStr.getDys393());
        }
        if (reportStr.getDys437() != null && Util.isDouble(reportStr.getDys437())) {
            strMap.put("dys437", reportStr.getDys437());
        }
        if (reportStr.getDys438() != null && Util.isDouble(reportStr.getDys438())) {
            strMap.put("dys438", reportStr.getDys438());
        }
        if (reportStr.getDys439() != null && Util.isDouble(reportStr.getDys439())) {
            strMap.put("dys439", reportStr.getDys439());
        }
        if (reportStr.getDys448() != null && Util.isDouble(reportStr.getDys448())) {
            strMap.put("dys448", reportStr.getDys448());
        }
        if (reportStr.getDys456() != null && Util.isDouble(reportStr.getDys456())) {
            strMap.put("dys456", reportStr.getDys456());
        }
        if (reportStr.getDys458() != null && Util.isDouble(reportStr.getDys458())) {
            strMap.put("dys458", reportStr.getDys458());
        }
        if (reportStr.getDys635() != null && Util.isDouble(reportStr.getDys635())) {
            strMap.put("dys635", reportStr.getDys635());
        }
        if (reportStr.getYgatah4() != null && Util.isDouble(reportStr.getYgatah4())) {
            strMap.put("y-gata-h4", reportStr.getYgatah4());
        }
        if (reportStr.getDys460() != null && Util.isDouble(reportStr.getDys460())) {
            strMap.put("dys460", reportStr.getDys460());
        }
        if (reportStr.getDys481() != null && Util.isDouble(reportStr.getDys481())) {
            strMap.put("dys481", reportStr.getDys481());
        }
        if (reportStr.getDys533() != null && Util.isDouble(reportStr.getDys533())) {
            strMap.put("dys533", reportStr.getDys533());
        }
        if (reportStr.getDys549() != null && Util.isDouble(reportStr.getDys549())) {
            strMap.put("dys549", reportStr.getDys549());
        }
        if (reportStr.getDys570() != null && Util.isDouble(reportStr.getDys570())) {
            strMap.put("dys570", reportStr.getDys570());
        }
        if (reportStr.getDys576() != null && Util.isDouble(reportStr.getDys576())) {
            strMap.put("dys576", reportStr.getDys576());
        }
        if (reportStr.getDys643() != null && Util.isDouble(reportStr.getDys643())) {
            strMap.put("dys643", reportStr.getDys643());
        }
        if (reportStr.getDys385a() != null && Util.isDouble(reportStr.getDys385a())) {
            strMap.put("dys385a", reportStr.getDys385a());
        }
        if (reportStr.getDys385b() != null && Util.isDouble(reportStr.getDys385b())) {
            strMap.put("dys385b", reportStr.getDys385b());
        }
        return strMap;
    }

    public Double getDistance(Map<String, String> strMap, Map<String, String> reportStrMap) {
        Double distance = 0.0;
        for (Map.Entry<String, String> entry : strMap.entrySet()) {
            if (reportStrMap.get(entry.getKey()) != null && Util.isDouble(reportStrMap.get(entry.getKey()))) {
                if (entry.getValue() != null && Util.isDouble(entry.getValue())) {
                    Double selfStrVal = Double.parseDouble(entry.getValue());
                    Double targetStrVal = Double.parseDouble(reportStrMap.get(entry.getKey()));
                    Double step = Math.abs(selfStrVal - targetStrVal);
                    distance += step;
                }
            }
        }

        return distance;
    }

    public Double getYear(Map<String, String> selfStrMap, Map<String, String> innerStrMap) {
//        Map<String,String> map = selfStrMap;
        Map<String,String> map = new HashMap<>();
        for (Map.Entry<String,String> each : selfStrMap.entrySet()) {
            if (!each.getKey().equals("dys385a") && !each.getKey().equals("dys385b") && !each.getKey().equals("dyf387s1") && !each.getKey().equals("dys527b") && !each.getKey().equals("dys527a")) {
                map.put(each.getKey(),each.getValue());
            }

        }
//        if (map.containsKey("dys385a")) {
//            map.remove("dys385a");
//        }
//        if (map.containsKey("dys385b")) {
//            map.remove("dys385b");
//        }
//        if (map.containsKey("dyf387s1")) {
//            map.remove("dyf387s1");
//        }
//        if (map.containsKey("dys527b")) {
//            map.remove("dys527b");
//        }
//        if (map.containsKey("dys527a")) {
//            map.remove("dys527a");
//        }
        int strCount = getIntersectionNum(map, innerStrMap);
        Double yearSum = 0.0;
        Map<String, Double> yearU = getYearU();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (entry.getValue() != null && Util.isDouble(entry.getValue())) {
                Double selfStrVal = Double.parseDouble(entry.getValue());
                if (innerStrMap.get(entry.getKey()) != null && Util.isDouble(innerStrMap.get(entry.getKey()))) {
                    Double targetStrVal = Double.parseDouble(innerStrMap.get(entry.getKey()));
                    Double coefficient = yearU.get(entry.getKey());
                    if (coefficient == null) {
                        coefficient = 0.01;
                        Double yearStep = Math.pow(selfStrVal - targetStrVal, 2) / 2 / coefficient;
                        yearSum += yearStep;
                    }
                    Double yearStep = Math.pow(selfStrVal - targetStrVal, 2) / 2 / coefficient;
                    yearSum += yearStep;
                }
            }
        }
        Double year = yearSum / strCount * 30;
        return year;
    }

    public Map<String, Double> getYearU() {
        Map<String, Double> map = new HashMap<>();
        map.put("dys19", 0.002299);
        map.put("dys389i", 0.002523);
        map.put("dys389b", 0.004176024);
        map.put("dys390", 0.002012);
        map.put("dys391", 0.002804321);
        map.put("dys392", 0.0004123);
        map.put("dys393", 0.001045);
        map.put("dys437", 0.001226);
        map.put("dys438", 0.000994175);
        map.put("dys439", 0.005214);
        map.put("dys448", 0.0020423);
        map.put("dys456", 0.005498928);
        map.put("dys458", 0.0069273);
        map.put("dys635", 0.003467);
        map.put("y-gata-h4", 0.002818572);
        map.put("dys460", 0.00252318);
        map.put("dys481", 0.004115267);
        map.put("dys533", 0.002202921);
        map.put("dys549", 0.003144102);
        map.put("dys570", 0.004165133);
        map.put("dys576", 0.004940979);
        map.put("dys643", 0.002125402);
        return map;
    }

    /**
     * 从给定的公共数据库记录中提取出对应位点信息
     *
     * @param reportPublicStr
     * @return
     */
    public Map<String, String> getPublicStrLib(ReportPublicStr reportPublicStr) {
        Map<String, String> map = new HashMap<>();
        List<ReportSiteValue> reportSiteValues = reportPublicStr.getReportSiteValues();
        for (ReportSiteValue reportPublicStr1 : reportSiteValues) {
            if (reportPublicStr1.getSiteName() != null && reportPublicStr1.getSiteValue() != null) {
                map.put(reportPublicStr1.getSiteName().toLowerCase(), reportPublicStr1.getSiteValue());
            }
        }
        return map;
    }

    /**
     * 获取两个位点之间的交集
     *
     * @param selfStrMap
     * @param outStrMap
     * @return
     */
    public Integer getIntersectionNum(Map<String, String> selfStrMap, Map<String, String> outStrMap) {
        Map<String, String> newMap = new HashMap<>();
        for (Map.Entry<String, String> entry : selfStrMap.entrySet()) {
            String key1 = entry.getKey();
            if (outStrMap.get(key1) != null) {
                newMap.put(key1, outStrMap.get(key1));
            }
        }
        return newMap.size();
    }

    /**
     * 从手动输入的位点信息中提取出将要参与比对的位点信息
     *
     * @param str
     * @return
     */
    public Map<String, String> extractManualStrInfo(String str) {
        Map<String, String> strMap = (Map<String, String>) JSON.parse(str);
        Map<String, String> returnMap = new HashMap<>();
        for (Map.Entry<String, String> entry : strMap.entrySet()) {
            if (Util.isDouble(entry.getValue())) {
                returnMap.put(entry.getKey(), entry.getValue());
            }
        }
        return returnMap;
    }
}
